commonlibsse_ng\re\a/
Actor.rs

1mod enums;
2mod local_map;
3mod runtime_data;
4
5pub use self::enums::*;
6pub use self::local_map::*;
7pub use self::runtime_data::ACTOR_RUNTIME_DATA;
8
9use crate::re::BSAnimationGraphEvent::BSAnimationGraphEvent;
10use crate::re::BSCoreTypes::RefHandle;
11use crate::re::BSTEvent::BSTEventSink;
12use crate::re::FormTypes::FormType;
13use crate::re::InventoryEntryData::InventoryEntryData;
14use crate::re::Misc::LookupReferenceByHandle_ActorImpl;
15use crate::re::NiSmartPointer::NiPointer;
16use crate::re::SpellItem::SpellItem;
17use crate::re::TESFaction;
18use crate::re::TESObjectREFR::{TESObjectREFR, TESObjectREFRVtbl};
19use crate::re::offsets_rtti::RTTI_Actor;
20use crate::re::offsets_vtable::VTABLE_Actor;
21use crate::rel::id::VariantID;
22use crate::rel::relocation::RelocationError;
23use crate::rel::relocation::relocate_member_if_newer;
24use crate::rel::relocation::relocate_member_if_newer_mut;
25use crate::skse::version::RUNTIME_SSE_1_6_629;
26use core::ptr::NonNull;
27
28#[repr(C)]
29#[derive(Debug)]
30pub struct Actor {
31    pub __base: TESObjectREFR,
32}
33const _: () = assert!(core::mem::size_of::<Actor>() == 0x78);
34
35impl Actor {
36    /// Address & offset of the runtime type information (RTTI) identifier.
37    pub const RTTI: VariantID = RTTI_Actor;
38
39    /// Address & offset of the virtual function table.
40    ///
41    /// The number of tables is the same as the number of classes with inherited virtual functions.
42    pub const VTABLE: [VariantID; 10] = VTABLE_Actor;
43
44    /// The `FormType` value for Actor.
45    pub const FORM_TYPE: FormType = FormType::ActorCharacter;
46
47    /// Get runtime offset definition fields.
48    ///
49    /// # Errors
50    /// - This function may return an error if the module's state cannot be accessed, or if the `map_active` call fails when fetching the current version.
51    /// - If the pointer is null
52    /// - If the pointer is unaligned
53    #[inline]
54    pub fn get_actor_runtime_data(&self) -> Result<&ACTOR_RUNTIME_DATA, RelocationError> {
55        unsafe { relocate_member_if_newer(RUNTIME_SSE_1_6_629, self, 0xE0, 0xE8) }
56    }
57
58    /// Get mutable runtime offset definition fields.
59    ///
60    /// # Errors
61    /// - This function may return an error if the module's state cannot be accessed, or if the `map_active` call fails when fetching the current version.
62    /// - If the pointer is null
63    /// - If the pointer is unaligned
64    #[inline]
65    pub fn get_actor_runtime_data_mut(
66        &mut self,
67    ) -> Result<&mut ACTOR_RUNTIME_DATA, RelocationError> {
68        unsafe { relocate_member_if_newer_mut(RUNTIME_SSE_1_6_629, self, 0xE0, 0xE8) }
69    }
70
71    #[inline]
72    pub fn lookup_reference_by_handle(ref_handle: RefHandle) -> NiPointer<Self> {
73        let mut actor_ptr = NiPointer::new();
74        LookupReferenceByHandle_ActorImpl(&ref_handle, &mut actor_ptr);
75        actor_ptr
76    }
77
78    #[inline]
79    pub fn lookup_by_handle_actor(ref_handle: RefHandle, refr_out: &mut NiPointer<Self>) -> bool {
80        LookupReferenceByHandle_ActorImpl(&ref_handle, refr_out)
81    }
82
83    pub fn add_animation_graph_event_sink(
84        &self,
85        sink: *mut BSTEventSink<BSAnimationGraphEvent>,
86    ) -> bool {
87        let mut graph_manager = match self.__base.__base3.get_animation_graph_manager() {
88            Some(graph) => graph,
89            None => return false,
90        };
91
92        let mut sinked = false;
93        for anim_graph in &graph_manager.graphs {
94            if sinked {
95                break;
96            }
97
98            for other_sink in &anim_graph.__base3.sinks {
99                if sink == *other_sink {
100                    sinked = true;
101                    break;
102                }
103            }
104        }
105
106        if !sinked {
107            let anim_graph = match graph_manager.graphs.get_mut(0) {
108                Some(sink) => sink,
109                None => return false,
110            };
111            anim_graph.__base3.add_event_sink(sink);
112            return true;
113        };
114
115        false
116    }
117
118    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 37787, ae_id = 38736)]
119    pub fn add_cast_power(&mut self, power: Option<NonNull<SpellItem>>) {}
120
121    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 36218, ae_id = 3719371937198)]
122    pub fn add_death_items(&mut self) {}
123
124    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 37771, ae_id = 38716)]
125    pub fn add_spell(&mut self, spell: Option<NonNull<SpellItem>>) {}
126
127    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 36678, ae_id = 37686)]
128    pub fn add_to_faction(&mut self, faction: Option<NonNull<TESFaction>>, rank: u8) {}
129
130    #[inline]
131    pub fn get_equipped_entry_data(&self, left_hand: bool) -> Option<NonNull<InventoryEntryData>> {
132        let proc = unsafe {
133            let current_process = self.get_actor_runtime_data().ok()?.currentProcess.as_ref()?;
134            current_process.middleHigh.as_ref()
135        }?;
136        match left_hand {
137            true => NonNull::new(proc.leftHand),
138            false => NonNull::new(proc.rightHand),
139        }
140    }
141}
142
143impl crate::re::NiSmartPointer::RefCountable for Actor {
144    #[inline]
145    fn inc_ref_count(&self) {
146        self.__base.__base1.__base.inc_ref_count();
147    }
148
149    #[inline]
150    fn dec_ref_count(&mut self) {
151        self.__base.__base1.__base.dec_ref_count();
152    }
153}
154
155pub struct ActorVtbl {
156    pub __base: TESObjectREFRVtbl,
157}
158const _: () = {
159    const VTABLE_SIZE: usize = core::mem::size_of::<ActorVtbl>();
160    const EXPECTED_SIZE: usize = (0x129 + 1) * core::mem::size_of::<usize>();
161    // assert!(VTABLE_SIZE == EXPECTED_SIZE);
162};